package com.lifeverse.entity;

import com.lifeverse.entity.enums.CollaborationRole;
import jakarta.persistence.*;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * 协作参与者实体类
 * 记录生命体在协作任务中的参与情况
 */
@Data
@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = "collaboration_participants", indexes = {
    @Index(name = "idx_collaboration_participant_task", columnList = "collaboration_task_id"),
    @Index(name = "idx_collaboration_participant_entity", columnList = "participant_id"),
    @Index(name = "idx_collaboration_participant_role", columnList = "role"),
    @Index(name = "idx_collaboration_participant_joined", columnList = "joined_at")
})
public class CollaborationParticipant extends BaseEntity {
    
    /**
     * 协作任务
     */
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "collaboration_task_id", nullable = false)
    private CollaborationTask collaborationTask;
    
    /**
     * 参与者（生命体）
     */
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "participant_id", nullable = false)
    private LifeEntity participant;
    
    /**
     * 协作角色
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "role", nullable = false, length = 20)
    private CollaborationRole role;
    
    /**
     * 参与状态
     */
    @Column(name = "participation_status", nullable = false, length = 20)
    private String participationStatus = "ACTIVE";
    
    /**
     * 加入时间
     */
    @Column(name = "joined_at", nullable = false)
    private LocalDateTime joinedAt;
    
    /**
     * 离开时间
     */
    @Column(name = "left_at")
    private LocalDateTime leftAt;
    
    /**
     * 贡献度评分（0-100）
     */
    @Column(name = "contribution_score", precision = 5, scale = 2)
    private BigDecimal contributionScore;
    
    /**
     * 协作效果评分（0-100）
     */
    @Column(name = "collaboration_effectiveness", precision = 5, scale = 2)
    private BigDecimal collaborationEffectiveness;
    
    /**
     * 参与度（0-100）
     */
    @Column(name = "engagement_level", precision = 5, scale = 2)
    private BigDecimal engagementLevel;
    
    /**
     * 技能匹配度（0-100）
     */
    @Column(name = "skill_match", precision = 5, scale = 2)
    private BigDecimal skillMatch;
    
    /**
     * 投入时间（分钟）
     */
    @Column(name = "time_invested", nullable = false)
    private Long timeInvested = 0L;
    
    /**
     * 完成任务数量
     */
    @Column(name = "tasks_completed", nullable = false)
    private Integer tasksCompleted = 0;
    
    /**
     * 提供帮助次数
     */
    @Column(name = "help_provided", nullable = false)
    private Integer helpProvided = 0;
    
    /**
     * 接受帮助次数
     */
    @Column(name = "help_received", nullable = false)
    private Integer helpReceived = 0;
    
    /**
     * 冲突次数
     */
    @Column(name = "conflicts_count", nullable = false)
    private Integer conflictsCount = 0;
    
    /**
     * 参与原因
     */
    @Column(name = "participation_reason", length = 500)
    private String participationReason;
    
    /**
     * 期望收益
     */
    @Column(name = "expected_benefit", precision = 10, scale = 2)
    private BigDecimal expectedBenefit;
    
    /**
     * 实际收益
     */
    @Column(name = "actual_benefit", precision = 10, scale = 2)
    private BigDecimal actualBenefit;
    
    /**
     * 学习成果
     */
    @Column(name = "learning_outcomes", columnDefinition = "TEXT")
    private String learningOutcomes;
    
    /**
     * 反馈意见
     */
    @Column(name = "feedback", columnDefinition = "TEXT")
    private String feedback;
    
    /**
     * 参与者标签（JSON格式）
     */
    @Column(name = "tags", length = 500)
    private String tags;
    
    /**
     * 参与者属性（JSON格式）
     */
    @Column(name = "attributes", columnDefinition = "TEXT")
    private String attributes;
    
    /**
     * 活动记录（JSON格式）
     */
    @Column(name = "activity_log", columnDefinition = "TEXT")
    private String activityLog;
    
    @PrePersist
    protected void onCreate() {
        super.onCreate();
        if (joinedAt == null) {
            joinedAt = LocalDateTime.now();
        }
    }
    
    /**
     * 离开协作
     */
    public void leave(String reason) {
        this.participationStatus = "LEFT";
        this.leftAt = LocalDateTime.now();
        this.participationReason = (this.participationReason != null ? this.participationReason + " | " : "") + 
                                  "离开原因: " + reason;
    }
    
    /**
     * 暂停参与
     */
    public void pause(String reason) {
        this.participationStatus = "PAUSED";
        this.participationReason = (this.participationReason != null ? this.participationReason + " | " : "") + 
                                  "暂停原因: " + reason;
    }
    
    /**
     * 恢复参与
     */
    public void resume() {
        this.participationStatus = "ACTIVE";
    }
    
    /**
     * 增加投入时间
     */
    public void addTimeInvested(long minutes) {
        this.timeInvested += minutes;
    }
    
    /**
     * 完成任务
     */
    public void completeTask() {
        this.tasksCompleted++;
    }
    
    /**
     * 提供帮助
     */
    public void provideHelp() {
        this.helpProvided++;
    }
    
    /**
     * 接受帮助
     */
    public void receiveHelp() {
        this.helpReceived++;
    }
    
    /**
     * 记录冲突
     */
    public void recordConflict() {
        this.conflictsCount++;
    }
    
    /**
     * 计算参与时长（分钟）
     */
    public long getParticipationDurationMinutes() {
        if (joinedAt == null) {
            return 0;
        }
        
        LocalDateTime endTime = leftAt != null ? leftAt : LocalDateTime.now();
        return java.time.Duration.between(joinedAt, endTime).toMinutes();
    }
    
    /**
     * 计算帮助比率
     */
    public BigDecimal getHelpRatio() {
        if (helpReceived == 0) {
            return helpProvided > 0 ? BigDecimal.valueOf(100) : BigDecimal.ZERO;
        }
        
        return BigDecimal.valueOf(helpProvided)
                .divide(BigDecimal.valueOf(helpReceived), 4, java.math.RoundingMode.HALF_UP);
    }
    
    /**
     * 计算冲突率
     */
    public BigDecimal getConflictRate() {
        long participationDays = getParticipationDurationMinutes() / (24 * 60);
        if (participationDays == 0) {
            return BigDecimal.ZERO;
        }
        
        return BigDecimal.valueOf(conflictsCount)
                .divide(BigDecimal.valueOf(participationDays), 4, java.math.RoundingMode.HALF_UP);
    }
    
    /**
     * 判断是否活跃参与
     */
    public boolean isActiveParticipant() {
        return "ACTIVE".equals(participationStatus);
    }
    
    /**
     * 判断是否已离开
     */
    public boolean hasLeft() {
        return "LEFT".equals(participationStatus);
    }
    
    /**
     * 判断是否暂停参与
     */
    public boolean isPaused() {
        return "PAUSED".equals(participationStatus);
    }
    
    /**
     * 计算收益率
     */
    public BigDecimal calculateBenefitRate() {
        if (expectedBenefit == null || expectedBenefit.compareTo(BigDecimal.ZERO) == 0) {
            return BigDecimal.ZERO;
        }
        
        if (actualBenefit == null) {
            return BigDecimal.ZERO;
        }
        
        return actualBenefit.divide(expectedBenefit, 4, java.math.RoundingMode.HALF_UP);
    }
    
    /**
     * 计算综合评分
     */
    public BigDecimal calculateOverallScore() {
        BigDecimal score = BigDecimal.ZERO;
        int factors = 0;
        
        if (contributionScore != null) {
            score = score.add(contributionScore);
            factors++;
        }
        
        if (collaborationEffectiveness != null) {
            score = score.add(collaborationEffectiveness);
            factors++;
        }
        
        if (engagementLevel != null) {
            score = score.add(engagementLevel);
            factors++;
        }
        
        if (skillMatch != null) {
            score = score.add(skillMatch);
            factors++;
        }
        
        if (factors == 0) {
            return BigDecimal.ZERO;
        }
        
        return score.divide(BigDecimal.valueOf(factors), 2, java.math.RoundingMode.HALF_UP);
    }
}